package com.dodo.blog.ui.component.composite;

import com.dodo.blog.RequestCycle;
import com.dodo.blog.model.Article;
import com.dodo.blog.model.Category;
import com.dodo.blog.request.BasicRequest;
import com.dodo.blog.server.ArticleService;
import com.dodo.blog.server.CategoryService;
import com.dodo.blog.server.TagService;
import com.dodo.blog.ui.component.container.Panel;
import com.dodo.blog.ui.component.input.Anchor;
import com.dodo.blog.ui.component.repeater.OrderDirection;
import com.dodo.blog.ui.util.Localization;
import com.dodo.blog.ui.util.UriConstructor;
import com.google.inject.Injector;

import java.text.MessageFormat;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author <a href="mailto:pohorelec@comvai.com">Jozef Pohorelec</a>
 */
public class AsidePanel
        extends Panel
{
    private static TagService tagService;

    private static CategoryService categoryService;

    private static ArticleService articleService;

    private static Logger log = Logger.getLogger( AsidePanel.class.getName() );

    private static String[] randomFontSizes = new String[]
            {
                    "20", "10", "18", "11", "13",
                    "21", "11", "16", "17", "8",
            };

    static
    {
        try
        {
            Injector injector = RequestCycle.get().getInjector();

            tagService = injector.getInstance( TagService.class );
            categoryService = injector.getInstance( CategoryService.class );
            articleService = injector.getInstance( ArticleService.class );
        }
        catch ( Exception e )
        {
            log.log( Level.SEVERE, "Error occurred during injecting services:", e );
        }
    }

    public enum Type
    {
        MOST_VIEWED( "mostViewed", "aside-panel-title-most-viewed" ),
        BEST_RATED( "bestRated", "aside-panel-title-best-rated" ),
        RECENT_POSTS( "recentPosts", "aside-panel-title-recent-posts" ),
        CATEGORIES( "categories", "aside-panel-title-categories" ),
        TAGS( "tags", "aside-panel-title-tags" );

        private String label;

        private String className;

        Type( String label, String className )
        {
            this.label = label;
            this.className = className;
        }

        public String getClassName()
        {
            return className;
        }

        public String getLabel()
        {
            return label;
        }
    }

    public AsidePanel( Type type )
    {
        setClassName( "aside-panel" );

        Panel titleWrapper = new Panel();
        titleWrapper.setClassName( "aside-panel-title-wrapper" );
        add( titleWrapper );

        Panel titlePanel = new Panel();
        titlePanel.setClassName( "aside-panel-title" );
        titlePanel.addClassName( type.getClassName() );
        titlePanel.setInnerHtml( Localization.localize( "title." + type.getLabel() ) );
        titleWrapper.add( titlePanel );

        Panel triangle = new Panel();
        triangle.setClassName( "aside-panel-triangle" );
        titleWrapper.add( triangle );

        switch ( type )
        {
            case MOST_VIEWED:
            {
                renderMostViewed();
                break;
            }
            case BEST_RATED:
            {
                renderBestRated();
                break;
            }
            case RECENT_POSTS:
            {
                renderRecent();
                break;
            }
            case CATEGORIES:
            {
                renderCategories();
                break;
            }
            case TAGS:
            {
                renderTags();
                break;
            }
        }
    }

    private void renderMostViewed()
    {
        renderArticles( articleService.getMostViewedArticles() );
    }

    private void renderBestRated()
    {
        renderArticles( articleService.getBestRatedArticles() );
    }

    private void renderRecent()
    {
        renderArticles( articleService.getRecentArticles() );
    }

    private void renderCategories()
    {
        BasicRequest request = new BasicRequest();
        request.addSort( "name", OrderDirection.ASC );
        for ( Category category : categoryService.getCategoryList( request ) )
        {
            renderAsideItem( category.getLabel(), UriConstructor.createCategoyUri( category ), null );
        }
    }

    private void renderTags()
    {
        BasicRequest request = new BasicRequest();
        request.addSort( "name", OrderDirection.ASC );

        Panel asideItem = new Panel();
        asideItem.setClassName( "aside-item-tag" );
        add( asideItem );

        int i = 0;
        for ( com.dodo.blog.model.Tag tag : tagService.getTagList( request ) )
        {
            Anchor anchor = renderAsideItem( tag.getLabel(), UriConstructor.createTagUri( tag ), randomFontSizes[i] );
            asideItem.add( anchor );
            i++;
            if ( i >= randomFontSizes.length )
            {
                i = 0;
            }
        }
    }

    private void renderArticles( List<Article> articles )
    {
        for ( Article article : articles )
        {
            renderAsideItem( article.getTitle(), UriConstructor.createArticleUri( article ), null );
        }
    }

    private Anchor renderAsideItem( String title, String url, String randomSize )
    {
        if ( randomSize != null )
        {
            Anchor asideItemLink = new Anchor( "", title, url );
            asideItemLink.setClassName( "aside-item-link" );
            asideItemLink.setStyle( MessageFormat.format( "font-size:{0}px;", randomSize ) );
            return asideItemLink;
        }
        else
        {
            Panel asideItem = new Panel();
            asideItem.setClassName( "aside-item" );
            add( asideItem );

            Panel asideItemStar = new Panel();
            asideItemStar.setClassName( "aside-item-star" );
            asideItem.add( asideItemStar );

            Anchor asideItemLink = new Anchor( "", title, url );
            asideItemLink.setClassName( "aside-item-link" );
            asideItem.add( asideItemLink );
        }

        return null;
    }
}